package com.zlzlib.libnetty.tcp;


import com.zlzlib.libnetty.base.BaseChannelInitializer;
import com.zlzlib.libnetty.base.BaseClient;
import com.zlzlib.libnetty.tcp.handler.HeartbeatRespHandler;
import com.zlzlib.libnetty.tcp.handler.LoginAuthRespHandler;
import com.zlzlib.libnetty.tcp.handler.TCPReadHandler;

import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

/**
 * Created by zlz on 2019/11/19.
 * Channel初始化配置
 */
public class TCPChannelInitializer<T> extends BaseChannelInitializer<SocketChannel> {

    private final BaseClient<T> imsClient;

    public TCPChannelInitializer(BaseClient<T> imsClient) {
        this.imsClient = imsClient;
    }

    @Override
    protected void initChannel(SocketChannel channel) throws Exception {
        ChannelPipeline pipeline = channel.pipeline();
        settingChannelPipeline(pipeline);
        // 握手认证消息响应处理handler
        pipeline.addLast(LoginAuthRespHandler.class.getSimpleName(), new LoginAuthRespHandler<>(imsClient));
        // 心跳消息响应处理handler
        pipeline.addLast(HeartbeatRespHandler.class.getSimpleName(), new HeartbeatRespHandler<>(imsClient));
        // 接收消息处理handler
        pipeline.addLast(TCPReadHandler.class.getSimpleName(), new TCPReadHandler<>(imsClient));
    }

    //可以配置一些编码方式
    protected void settingChannelPipeline(ChannelPipeline pipeline) {
        //这里需要和服务端统一不然无法发送接收消息
        // netty提供的自定义长度解码器，解决TCP拆包/粘包问题
        pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,
                0, 4, 0, 4));
        pipeline.addLast("frameEncoder", new LengthFieldPrepender(4));
        pipeline.addLast("decoder", new StringDecoder());
        pipeline.addLast("encoder", new StringEncoder());
//        // 增加protobuf编解码支持
//        pipeline.addLast(new ProtobufEncoder());
//        pipeline.addLast(new ProtobufDecoder(MessageProtobuf.Msg.getDefaultInstance()));
    }

}
